package practise;
import static com.googlecode.objectify.ObjectifyService.ofy;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.TreeSet;

import javax.inject.Named;

import practise.APIResponse.Status;

import com.google.api.server.spi.config.Api;
import com.google.api.server.spi.config.ApiMethod;
import com.google.api.server.spi.config.ApiMethod.HttpMethod;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Ref;

@Api(name = "maxsizetest")
public class MaxsizeTest {
	
	static {		
		ObjectifyService.factory().register(SetOfLongEntity.class);		
		ObjectifyService.factory().register(ListofLongEntity.class);
		ObjectifyService.factory().register(TextEntity.class);
		ObjectifyService.factory().register(SetofStringEntity.class);
		ObjectifyService.factory().register(EntityWithRef.class);
		ObjectifyService.factory().register(SerializedSetEntity.class);
	}
	
	@ApiMethod(httpMethod = HttpMethod.PUT, path = "createsetoflong")
	public APIResponse createSetOfLong(@Named("num_elements") Long numElements) {
		
		try {
			//can go upto 71000
			SetOfLongEntity entity = new SetOfLongEntity();
			
			entity.set = new TreeSet<Long>();
			
			for (long i = 0; i < numElements; i++) {
				entity.set.add(i);
			}
			
			ofy().save().entity(entity).now();
			return new APIResponse(Status.SUCCESS, 
					"created set of long with numElements [" + numElements + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse createSetOfSerializedSet(@Named("num_elements") Long numElements) {
		try {
			//can go upto 400,000
			SerializedSetEntity entity = new SerializedSetEntity();
			
			entity.set = new HashSet<Long>();
			
			for (long i = 10000000; i < 10000000 + numElements; i++) {
				entity.set.add(i);
			}
			
			ofy().save().entity(entity).now();
			
			long id = entity.id;
			entity = ofy().cache(false).load().type(SerializedSetEntity.class).id(id).get();
			
			return new APIResponse(Status.SUCCESS, 
					"created set of int with numElements [" + entity.set.size() + 
					"]. id = [" + entity.id + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse getNumElementsInSerializedSet(@Named("serialized_set_id") Long setId) {
		try {
			
			SerializedSetEntity entity = ofy().load().type(SerializedSetEntity.class).id(setId).get();
			
			long max = 0;
			for (long element : entity.set) {
				if (element > max)
					max = element;
			}
			
			return new APIResponse(Status.SUCCESS, 
					"num elements = [" + entity.set.size() + 
					"]. id = [" + entity.id + "], max = [" + max + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse createListOfLong(@Named("num_elements") Long numElements) {
		
		try {
			//can go upto 66000 elements
			ListofLongEntity entity = new ListofLongEntity();
			
			entity.list = new ArrayList<Long>();
			
			for (long i = 0; i < numElements; i++) {
				entity.list.add(i);
			}
			
			ofy().save().entity(entity).now();
			return new APIResponse(Status.SUCCESS, 
					"created list of long with numElements [" + numElements + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}
	
	public APIResponse createText(@Named("num_char") Long numChar) {
		
		try {
			//can go upto 1 million characters			
			
			StringBuilder builder = new StringBuilder();
			
			for (long i = 0; i < numChar/26; i++)
				builder.append("abcdefghijklmnopqrstuvwxyz");
				
			TextEntity entity = new TextEntity();
			entity.text = builder.toString();
			
			ofy().save().entity(entity).now();
			return new APIResponse(Status.SUCCESS, 
					"created list of long with numChar [" + numChar + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}

	public APIResponse createStringSetWith25Char(
			@Named("num_elements") Long numElements) {
		
		try {
			//can go up to 20000 elements in the set			
			
			String s = "abcdefghijklmnopqrstuvwxyz";
						
			SetofStringEntity entity = new SetofStringEntity();
			entity.set = new HashSet<>();
			
			for (long i = 0; i < numElements; i++) {
				entity.set.add(s + i);
			}			
			
			ofy().save().entity(entity).now();
			
			entity = ofy().load().type(SetofStringEntity.class).id(entity.id).get();
						
			return new APIResponse(Status.SUCCESS, 
					"created set of string (26 char each) with numElements [" + entity.set.size() + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}

	public APIResponse createEntityWithRef(
			@Named("num_references") Long numReferences) {
		
		try {
			
			//can go upto 24000
			
			EntityWithRef entityWithRef = new EntityWithRef();			
			
			TextEntity entity = new TextEntity();
			ofy().save().entity(entity).now();
			
			for (long i = 0; i < numReferences; i++) {
				entityWithRef.list.add(Ref.create(entity));		
			}
			ofy().save().entity(entityWithRef).now();
								
			return new APIResponse(Status.SUCCESS, 
					"created entity with no of key references = [" + numReferences + "]");
			
		} catch (APIException ex) {
			return new APIResponse(ex);
		}
	}
}
